package com.example.aop;

import cn.hutool.crypto.SecureUtil;
import com.example.annotation.Idempotent;
import com.example.util.RedisUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 幂等校验拦截器
 * @author long
 * @date 2024/12/30 13:32
 */
@Component
public class IdempotentInterceptor implements HandlerInterceptor {

    @Resource
    private RedisUtils redisUtils;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        if(!(handler instanceof HandlerMethod)){
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        Idempotent methodAnnotation = method.getAnnotation(Idempotent.class);
        // 方法上面没有加注解 则不拦截
        if (Objects.isNull(methodAnnotation)) {
            return true;
        }

        String uri = request.getRequestURL().toString();
        String token = request.getHeader("Authorization");
        String md5Key = SecureUtil.md5(String.join("_",uri,token));
        String redisKey = methodAnnotation.prefix()+"::"+md5Key;

        // 第一次访问
        if(!redisUtils.exists(redisKey)){
            redisUtils.set(redisKey,uri,methodAnnotation.expire());
            return true;
        }else{
            throw new RuntimeException("请求太频繁，请稍等");
        }
    }

}
